package edu.mercer.medapps.documentbldr;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import com.google.common.base.Optional;
import com.google.common.collect.Range;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkArgument;

/**
 * Validate file: readable regular file.<p>
 * 
 * Verifies readable, not a directory, device.<p>
 * 
 */

public class ValidFile 
{	
	final static Range<Integer> LENGTH_PERMITTED = Range.closed(1, 220);

	private Optional<String> _filename = Optional.absent();
	
	private Optional<Path>   _filepath = Optional.absent();

	private Boolean _valid = false;
	
	/**
	 * Validate file: readable regular file.<p>
	 * 
	 * @param fileNameIn - String filename with any path, not null
	 *  
	 * @throws IllegalArgumentEception  file unreadable, or is a directory, 
	 * 	device
	 */
	
	ValidFile(final String fileNameIn)
	{
		super();
		
		_valid = false;
		
		checkNotNull( fileNameIn, "null detected: filename argument" );

		checkArgument( LENGTH_PERMITTED.contains(fileNameIn.length()),
				
				"filename and or path too long, maximum length : " +
				LENGTH_PERMITTED.upperEndpoint() );
		
		_filename = Optional.of(fileNameIn);
		
		_filepath = Optional.of(Paths.get(fileNameIn));
		
		this.isReadable()
			.isRegularFile();

		_valid = true;
		
	}//constructor


	/**
	 * Ensure file is readable.<p>
	 *
	 * @return ValidFile - instance of this
	 * 
	 * @throws IllegalArgumentEception  file unreadable
	 */
	
	private ValidFile isReadable()
	{
		checkArgument( Files.isReadable(_filepath.get()), 
				"file unreadable : " + _filename.get() );
		
		return this;
		
	}//method

	
	/**
	 * Ensure file is regular file.<p>
	 *
	 * @return ValidFile - instance of this
	 * 
	 * @throws IllegalArgumentEception  file is directory, device
	 */
	
	private ValidFile isRegularFile()
	{
		checkArgument( Files.isRegularFile(_filepath.get()), 
				"not a regular file : " + _filename.get() );
		
		return this;
		
	}//method

	
	/**
	 * Predicate method if file is valid.<p> 
	 *  
	 * @return Boolean - T if file is readable, is regular file 
	 */
	
	Boolean isValid()
	{
		return _valid;
		
	}//method
	
	
	@Override
	public String toString(){ return _filename.get(); }
	
}//class
